import { asyncRoutes, constantRoutes, previewRoutes } from '@/router'
import { queryMenusByUser } from './api.js'
import { MessageBox, Message } from 'element-ui'
import { getToken, setToken, removeToken, setRefreshToken, getRefreshToken, removeRefreshToken, getAuths, setAuths, removeAuths, getUser, setUser, removeUser } from '@/utils/auth'
/* Layout */
// import Layout from '@/layout'
// import TmptPreview from '@/views/tmpt/tmpt-preview'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: [],
  routerCrumbList: []
}

const mutations = {
  SET_PRE_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  },
  SET_ROUTES: (state, routes) => {
    state.addRoutes = state.addRoutes.concat(routes)
    state.routes = state.routes.concat(routes)
  },
  Clear_Routes: (state) => {
    state.routes = []
    state.addRoutes = []
  },
  SET_CrumbList: (state, routerCrumbList) => {
    state.routerCrumbList = routerCrumbList
  },
}

import Vue from 'vue'
import TmptPreview from '@/views/tmpt/tmpt-preview.vue';
import TmptActivitiFrom from '@/views/tmpt/activiti/tmpt-form-input.vue';
import Layout from '@/layout';

function reduceMenu (menuList, routeList) {
    if (menuList === undefined || menuList.length === 0) {
        return null
    }
    for (let i=0; i<menuList.length; i++) {
        let menu = menuList[i]
        let nameEn = menu.nameEn===''? ''+menu.id:menu.nameEn
        const route = {}
        route.hidden = false
        route.alwaysShow = false

        // 备份的菜单：重复生成源码时，生成创建新的菜单，同时备份原菜单，原菜单='菜单名___123123'，原菜单路由里就不显示了
        if (menu.name.indexOf('___')!=-1) {
            continue
        }

        // preview
        if (nameEn === 'tmpt-preview') {
            //  create module dynamic
            Vue.component("app", {
              name:'Tmpt-Preview-' + menu.name,
              props: {
                keyRandomProp: String
              },
              data: function() {
                return {
                  keyRandom: ''
                };
              },
              template:
                '<div><div id="appId"/> </div>',

              watch: {
                keyRandomProp() {
                  this.keyRandom = this.keyRandomProp
                }
              },
              mounted() {
                this.keyRandom = this.$route.query.keyRandom
                if (this.keyRandom === undefined) {
                  this.keyRandom = this.keyRandomProp
                }
                this.insert()
              },
              methods: {
                insert() {
                  const bcConstructor = Vue.extend(TmptPreview);
                  const instance = new bcConstructor({
                    propsData:{
                      keyRandomProp: this.keyRandom
                    }
                  });
                  instance.$mount('#appId');
                }
              }
            });

            route.path = '/layout/'+menu.name
            route.component = Vue.component("app");
            route.param = { keyRandom: menu.url }
            route.name = 'Tmpt-Preview-' + menu.name // 与@/views/tmpt/tmpt-preview中设置的name对应
        }
        // activiti
        else if (nameEn === 'tmpt-activiti-form') {
            //  create module dynamic
            Vue.component("app", {
              name:'Tmpt-Activiti-Form-' + menu.name,
              props: {
                keyProp: String
              },
              data: function() {
                return {
                  key: ''
                };
              },
              template:
                '<div><div id="appId"/> </div>',

              watch: {
                keyProp() {
                  this.key = this.keyProp
                }
              },
              mounted() {
                this.key = this.$route.query.key
                if (this.key === undefined) {
                  this.key = this.keyProp
                }
                this.insert()
              },
              methods: {
                insert() {
                  const bcConstructor = Vue.extend(TmptActivitiFrom);
                  const instance = new bcConstructor({
                    propsData:{
                      keyProp: this.key
                    }
                  });
                  instance.$mount('#appId');
                }
              }
            });

            route.path = '/layout/'+menu.name
            route.component = Vue.component("app");
            route.param = { key: menu.url }
            route.name = 'Tmpt-Activiti-Form-' + menu.name // 与@/views/activiti/tmpt-form-input中设置的name对应
        }
        else{ // not preview
            route.path = '/layout/'+nameEn
            if (menu.url === undefined || menu.url === '') {
                // route.component = () => import('@/layout')
                route.component = Layout
            }else {
                //route.component = () => import(`@/views/${menu.url}`)
                //route.component = () => import('@/views/' + menu.url )
                // const myComponent = resolve => require(['@/views/' + menu.url],resolve);
                const myComponent = resolve => require.ensure([], () => resolve(require('@/views/' + menu.url )));
                route.component = myComponent;
                /*if (menu.url.indexOf('coding/base/')!==-1) {
                  const myComponent = resolve => require.ensure([], () => resolve(require('@/views/coding/base/' + menu.url.substr(menu.url.indexOf('coding/base/')+'coding/base/'.length)) ));
                  route.component = myComponent;
                }
                else if (menu.url.indexOf('coding/city/')!==-1) {
                  const myComponent = resolve => require.ensure([], () => resolve(require('@/views/coding/city/' + menu.url.substr(menu.url.indexOf('coding/city/')+'coding/city/'.length)) ));
                  route.component = myComponent;
                }
                else if (menu.url.indexOf('coding/citybuild/')!==-1) {
                  const myComponent = resolve => require.ensure([], () => resolve(require('@/views/coding/citybuild/' + menu.url.substr(menu.url.indexOf('coding/citybuild/')+'coding/citybuild/'.length)) ));
                  route.component = myComponent;
                }
                else if (menu.url.indexOf('coding/cityout/')!==-1) {
                  const myComponent = resolve => require.ensure([], () => resolve(require('@/views/coding/cityout/' + menu.url.substr(menu.url.indexOf('coding/cityout/')+'coding/cityout/'.length)) ));
                  route.component = myComponent;
                }
                else if (menu.url.indexOf('tmpt/')!==-1) {
                  const myComponent = resolve => require.ensure([], () => resolve(require('@/views/tmpt/' + menu.url.substr(menu.url.indexOf('tmpt/')+'tmpt/'.length)) ));
                  route.component = myComponent;
                }*/

            }
            route.name = nameEn
        }


        route.meta = {
            title: menu.name,
            icon: menu.iconClass===undefined || menu.iconClass===''?'table':menu.iconClass,
            // roles: ['tmpt:query'],
            cache: true
        }

        if (menu.url !== 'hidden' && menu.url !== 'hide' && menu.nameEn !== 'hidden' && menu.nameEn !== 'hide') {
            routeList.push(route)
        }

        reduceMenu(menu.children, route.children=[])
    }
}

const actions = {
  clearRoutes({ commit } ) {
      commit('Clear_Routes')
  },

  generateDynamicRoutes({ commit }, roles) {
      return new Promise(resolve => {
          queryMenusByUser().then(result => {
              if (!result.success) {
                console.log(result)
                Message({
                  message: result.content,
                  type: 'error',
                  duration: 5 * 1000
                })
                // clear token, 刷新页面会重新进登录页面
                removeToken()
                removeRefreshToken()
                removeAuths()
                removeUser()

                return;
              }
              if (result.success) {
                  // 重新登录时，state中可能有上次保留的数据，先清空一下
                  previewRoutes.splice(0)
                  // read the new routes
                  const menuList = result.list
                  const routeList = []

                  //
                  reduceMenu(menuList, previewRoutes)
                  routeList.forEach(route => {
                      previewRoutes.unshift(route)
                  })
                  console.log("previewRoutes")
                  console.log(previewRoutes)
                  // const previewRoutesFinal = filterAsyncRoutes(previewRoutes, roles)
                  const previewRoutesFinal = previewRoutes
                  commit('SET_PRE_ROUTES', previewRoutesFinal)
                  resolve(previewRoutes)
              }
          })
      })
  },


  generatePreviewRoutes({ commit }, roles) {
    const preview_menu_id = 667
    return new Promise(resolve => {
      getAuthsTree({ id: preview_menu_id }).then(result => {
        if (result.success) {
          // 重新登录时，state中可能有上次保留的数据，先清空一下
          previewRoutes[0].children.splice(0)
          // read the new routes
          const previewAuths = result.map.list
          previewAuths.forEach((auth) => {
            const route = {}
            route.path = auth.name

            //  create module dynamic
            Vue.component("app", {
              name:'Tmpt-Preview-' + auth.name,
              props: {
                keyRandomProp: String
              },
              data: function() {
                return {
                  keyRandom: ''
                };
              },
              template:
                '<div><div id="appId"/> </div>',

              watch: {
                keyRandomProp() {
                  this.keyRandom = this.keyRandomProp
                }
              },
              mounted() {
                this.keyRandom = this.$route.query.keyRandom
                if (this.keyRandom === undefined) {
                  this.keyRandom = this.keyRandomProp
                }
                this.insert()
              },
              methods: {
                insert() {
                  const bcConstructor = Vue.extend(TmptPreview);
                  const instance = new bcConstructor({
                    propsData:{
                      keyRandomProp: this.keyRandom
                    }
                  });
                  instance.$mount('#appId');
                }
              }
            });


            route.component = Vue.component("app");
            route.param = { keyRandom: auth.url }
            route.name = 'Tmpt-Preview-' + auth.name // 与@/views/tmpt/tmpt-preview中设置的name对应
            // route.name = 'Tmpt-Preview' // 与@/views/tmpt/tmpt-preview中设置的name对应
            route.meta = {
              title: auth.name,
              icon: 'table',
              roles: ['tmpt:query'],
              cache: true
            }
            previewRoutes[0].children.unshift(route)
          })

          const previewRoutesFinal = filterAsyncRoutes(previewRoutes, roles)
          commit('SET_PRE_ROUTES', previewRoutesFinal)
          resolve(previewRoutes)
        }
      })
    })
  },

  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      /* if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }*/
      accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  },

  setCrumbList({ commit }, routerCrumbList) {
    commit('SET_CrumbList', routerCrumbList)
  }

}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
